//package appapi.config;
//
//import appapi.dao.IotcountMapper;
//import appapi.entity.mqtt.*;
//import appapi.service.TerminalService;
//import appapi.utils.DateUtil;
//import appapi.utils.EquipTestUtils;
//import appapi.utils.OrderUtils;
//import appapi.utils.RedisUtils;
//import com.alibaba.fastjson.JSONObject;
//import org.eclipse.paho.client.mqttv3.*;
//import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.scheduling.annotation.EnableScheduling;
//import org.springframework.scheduling.annotation.Scheduled;
//
//import javax.annotation.Resource;
//import java.sql.*;
//import java.time.LocalDateTime;
//import java.util.*;
//import java.util.Date;
//import java.util.concurrent.ExecutorService;
//import java.util.concurrent.Executors;
//
///**
// * @version: java version 1.8
// * @Author: Ygp Work
// * @description:
// * @date: 2023-06-30 16:01
// */
//
//@Configuration
//@EnableScheduling
//public class MqttFactory extends Thread {
//
//    @Value("${mqtt.host}")
//    private String host;
//
//    @Resource
//    private RedisUtils redisUtils;
//    @Resource
//    TerminalService terminalService;
//    @Resource
//    IotcountMapper iotcountMapper;
//
//    public static Set<String> terms;
//
//    private final static Logger logger = LoggerFactory.getLogger(MqttFactory.class);
//
//    private static MqttFactory factory;
//
//    private static MqttClient CLIENT;
//    private String deviceNumber;
//
//    public MqttFactory() {
//        factory = this;
//    }
//
//    public static void sendMessage(String clientId, String topic, Object message) throws MqttException {
//        sendMessage(clientId, topic, JSONObject.toJSONString(message));
//    }
//
//    /**
//     * 发送信息
//     *
//     * @param clientId
//     * @param topic
//     * @param message
//     * @throws MqttException
//     */
//    public static void sendMessage(String clientId, String topic, String message) throws MqttException {
//        MqttMessage mqttMessage = new MqttMessage();
//        mqttMessage.setQos(1);
//        mqttMessage.setRetained(false);
//        mqttMessage.setPayload(message.getBytes());
//        try {
//            getClient(clientId).publish(topic, mqttMessage);
//            logger.info("主题【" + topic + "】发送消息成功：" + message);
//            if (logger.isDebugEnabled()) {
//                logger.debug("主题【" + topic + "】发送消息成功：" + message);
//            }
//        } catch (Exception e) {
//            logger.error("主题【" + topic + "】发送消息失败：" + e.getMessage() + "\n消息内容：" + message, e);
//        }
//    }
//
//    /**
//     * 容错判断，没有心跳10秒后发送断开命令
//     *
//     * @throws Exception
//     */
//    @Scheduled(cron = "0/1 * * * * ?")
//    private void startTimers() throws Exception {
//        try {
//            //拿到reids里存在的所有设备号
//            Set<String> keys = redisUtils.keys("*Online:*");
//            for (String term : keys) {
//                //获取该设备的存储时间
//                java.util.Date termTime = (java.util.Date) redisUtils.get(term);
//                //用存储的时间与当前时间做对比，如果大于10秒，则发送关闭信息，并且删除redis中的该设备键
//                if (DateUtil.dateDiff(termTime, new Date()) > 10) {
//                    String message = "当前设备在线";
//                    redisUtils.del(term);
//                }
//            }
//        } catch (Exception e) {
//            logger.info("没接到到心跳，当前设备已离线或者网络延迟暂时没有接收到心跳");
//        }
//    }
//
//    /**
//     * 订阅功能
//     *
//     * @param clientId
//     * @param topic
//     * @throws MqttException
//     */
//    public void subscribe(String clientId, String topic) throws MqttException {
//
//        getClient(clientId).subscribe(topic, 1, new IMqttMessageListener() {
//            @Override
//            public void messageArrived(String topic, MqttMessage message) throws Exception {
//                String data = message.toString();
//                Topic res = new Topic(topic);
//                if (res.getDataType().equals("Data")) {
//                }
//                JSONObject parse = (JSONObject) JSONObject.parse(data);
//                String command = parse.getString("command");
//                String upload = parse.getString("upload");
//                if (command == null || command.isEmpty()) {
//                    switch (upload) {
//                        //设备实时数据
//                        case "debug":
//                            redisUtils.set("Online:".concat(res.getEquiNo()), new Date(), EquipTestUtils.ORDER_EXPIRE);
//                            break;
//                        case "data":
////                            saveData(data);
//                            redisUtils.set(res.getEquiNo(), data);
//                            break;
//                        case "Data":
//                            redisUtils.set(res.getEquiNo(), data);
//                            //配置信息
//                        case "Threshold":
//                            savaAlerm(res, data);
//                            break;
//                        //告警
//                        case "alarm":
//                            savaAlerm(res, data);
//                            break;
//                        //GSM是物联网卡的信号数据
//                        case "gsm":
//                            break;
//                        case "Reply":
//                            break;
//                        case "Read":
//                            break;
//                        //工况设置
//                        case "Workset":
//                            savaAlerm(res, data);
//                            break;
//                        //力矩设置
//                        case "Moment":
//                            savaAlerm(res, data);
//                            break;
//                        //标定
//                        case "Calibration":
//                            savaAlerm(res, data);
//                            break;
//                        case "reginfo":
//                            savaAlerm(res, data);
//                            break;
//                        //摄像头位置设置
//                        case "Generic":
//                            savaAlerm(res, data);
//                            break;
//                        //吊钩补偿
//                        case "Camera":
//                            savaAlerm(res, data);
//                            break;
//                        //障碍物设置
//                        case "Obstacle":
//                            break;
//                        //传感器数据
//                        case "ValueAD":
//                            break;
//                        case "Status":
//                            redisUtils.set("Online:".concat(res.getEquiNo()), new Date(), EquipTestUtils.ORDER_EXPIRE);
//                            break;
//                        case "Demand":
//                            break;
//                        //截图
//                        case "Screenshot":
//                            savaAlerm(res, data);
//                            break;
//                        //截图
//                        case "AuthReport":
//                            savaAlerm(res, data);
//                            break;
//                        case "null":
//                            break;
//                    }
//                }
//                String payload = new String(message.getPayload());
//                // 在这里进行消息处理逻辑
//            }
//
//
//            /**
//             * 每秒订阅存到时序库
//             * @param data
//             * @throws ClassNotFoundException
//             * @throws SQLException
//             */
//            public void saveData(String data) throws ClassNotFoundException, SQLException {
//                // 加载类库
//                Class.forName("org.apache.iotdb.jdbc.IoTDBDriver");
//                // 建立连接
//                try (Connection connection = DriverManager.getConnection("jdbc:iotdb://162.14.116.194:6667/", "root", "root"); Statement statement = connection.createStatement()) {
//                    // 添加数据到时序数据库
//                    String insertStatement = "insert into root.Ygp.d1.s1(timestamp, value) values(now(), '" + data + "')";
//                    // 执行插入语句
//                    statement.executeUpdate(insertStatement);
//                }
//            }
//
//            /**
//             * 配置修改入库
//             * @param topic
//             * @param data
//             */
//            public void savaAlerm(Topic topic, String data) {
//                JSONObject parse = (JSONObject) JSONObject.parse(data);
//                String upload = parse.getString("upload");
//                Terminal terminal = new Terminal();
//                terminal.setTermId(String.valueOf(UUID.randomUUID()));
//                terminal.setTermNo(topic.getEquiNo());
//                terminal.setTermTopic(upload);
//                terminal.setTermData(data);
//                terminal.setCreateTime(LocalDateTime.now());
//                terminal.setUpdateTime(LocalDateTime.now());
//                Terminal terminalById = terminalService.getTerminalByIds(topic.getEquiNo(), upload);
//                if (terminalById == null) {
//                    terminalService.addTerminal(terminal);
//                } else {
//                    terminal.setTermId(terminalById.getTermId());
//                    terminalService.updateTerminal(terminal);
//                }
//            }
//
//        });
//    }
//
//    /**
//     * 订阅时间
//     */
//    @Scheduled(cron = "0/5 * * * * ?")
//    public void subscribeTask() {
//        //获取到topic中的设备唯一号
//        List<String> deviceNumbers = getTopic();
//        //增加一个线程池，大小是根绝那个设备传过来的数量
//        ExecutorService executorService = Executors.newFixedThreadPool(deviceNumbers.size());
//        for (String deviceNumber : deviceNumbers) {
//            executorService.execute(() -> {
//                //生成id
//                String clientId = UUID.randomUUID().toString();
//                //注意：这个deviceNumer为传过来的
//                String topic = "F/+/+/+/+/+/+/+/+/" + deviceNumber + "/+";
//                try {
//                    subscribe(clientId, topic);
//                } catch (MqttException e) {
//                }
//            });
//        }
//        executorService.shutdown();
//    }
//
//    public List<String> getTopic() {
//        List<String> deviceNumbers = new ArrayList<>();
//        deviceNumbers.add(deviceNumber);
//        return deviceNumbers;
//    }
//
//    public void setTopic(String deviceNumber) {
//        this.deviceNumber = deviceNumber.split("/")[9];
//    }
//
//    /**
//     * 配置做判断用的后面大部分用不到
//     *
//     * @param clientId
//     * @return
//     */
//    private static MqttClient getClient(String clientId) {
//
//        if (CLIENT != null) {
//            return CLIENT;
//        }
//        synchronized (MqttFactory.class) {
//            if (CLIENT != null) {
//                return CLIENT;
//            }
//            try {
//                CLIENT = createClient(clientId);
//            } catch (MqttException e) {
//                throw new RuntimeException(e.getMessage(), e);
//            }
//            return CLIENT;
//        }
//    }
//
//    /***
//     * 创建会话
//     * @param clientId
//     * @return
//     * @throws MqttException
//     */
//    private static MqttClient createClient(String clientId) throws MqttException {
//        MqttClient CLIENT = new MqttClient(factory.host, clientId, new MemoryPersistence());
//        MqttClient mqtts = new MqttClient(factory.host, clientId, new MemoryPersistence());
//        MqttConnectOptions options = new MqttConnectOptions();
//
//        //设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录，设置为true表示每次连接到服务器都以新的身份连接
//        options.setCleanSession(true);
//
//        //设置用户名密码
//        //options.setUserName(factory.username);
//        //options.setPassword(factory.password.toCharArray());
//
//        // 设置超时时间 单位为秒
//        options.setConnectionTimeout(10);
//
//        // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
//        options.setKeepAliveInterval(60);
//
//        //设置断开后重新连接
//        options.setAutomaticReconnect(true);
//
//        CLIENT.connect(options);
//
////        //初始化拿取reids里存在的所有设备号
////        Set<String> termList = (Set<String>)redisUtils.get("TermList");
////        terms.addAll(termList);
//
//        return CLIENT;
//    }
//}
